#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
@Project ：dynamic-multi-objective-optimization 
@File    ：demo-v0.1.py
@IDE     ：PyCharm 
@Author  ：Simon Zhang
@Date    ：2025/7/1 07:39 
'''
from pyomo.environ import *

# 创建一个模型
model = ConcreteModel()

# 定义集合
model.T = RangeSet(12)  # 假设有12个时间段

# 定义参数
model.demand = Param(model.T, initialize={1:100, 2:150, 3:200, 4:100, 5:90, 6:150, 7:300, 8:200, 9:220, 10:110, 11:190, 12:250})
model.production_cost = 10
model.storage_cost = 2
model.capacity = 500
model.storage_limit = 300

# 定义变量
model.production = Var(model.T, domain=NonNegativeReals)
model.sales = Var(model.T, domain=NonNegativeReals)
model.inventory = Var(model.T, domain=NonNegativeReals)

# 定义目标函数（多目标）
def profit_rule(model):
    return sum((model.sales[t] * 15 - model.production[t] * model.production_cost - model.inventory[t] * model.storage_cost) for t in model.T)

def delivery_delay_rule(model):
    return sum((model.demand[t] - model.sales[t]) for t in model.T if model.demand[t] > model.sales[t])

model.profit = Objective(rule=profit_rule, sense=maximize)
model.delivery_delay = Objective(rule=delivery_delay_rule, sense=minimize)

# 定义约束
def production_constraint_rule(model, t):
    return model.production[t] <= model.capacity

def inventory_balance_rule(model, t):
    if t == model.T.first():
        return model.inventory[t] == model.production[t] - model.sales[t]
    return model.inventory[t] == model.inventory[t-1] + model.production[t] - model.sales[t]

def demand_constraint_rule(model, t):
    return model.sales[t] <= model.demand[t]

def storage_limit_rule(model, t):
    return model.inventory[t] <= model.storage_limit

model.ProductionConstraint = Constraint(model.T, rule=production_constraint_rule)
model.InventoryBalance = Constraint(model.T, rule=inventory_balance_rule)
model.DemandConstraint = Constraint(model.T, rule=demand_constraint_rule)
model.StorageLimit = Constraint(model.T, rule=storage_limit_rule)

# 求解模型
solver = SolverFactory('glpk')
result = solver.solve(model, tee=True)

# 显示结果
model.production.display()
model.sales.display()
model.inventory.display()